import away3d.audio.*;
import away3d.cameras.*;
import away3d.cameras.lenses.*;
import away3d.containers.*;
import away3d.core.base.*;
import away3d.core.clip.*;
import away3d.core.math.*;
import away3d.events.*;
import away3d.extrusions.*;
import away3d.lights.*;
import away3d.loaders.*;
import away3d.materials.*;
import away3d.primitives.*;
import away3d.sprites.*;

import com.powerfl.frm.taf.*;

import flash.display.*;
import flash.media.*;
import flash.text.*;
import flash.utils.*;

final public function addExtrusionSkin( $parent:String, $key:String, $map:String, $precisionX:int, $precisionY:int, $scaleX:Number, $scaleY:Number, $scaleZ:Number, $channelRGBAV:String = 'r', $smooth:int = 0, ...$param ):void{
	var param:TAFparam;
	param = $paramGet( $param );
	orderAddByKeyCheck( $key, param, function():void{
		var reader:ElevationReader, elevate:Elevation, map:BitmapData, extrude:SkinExtrude, vars:TAFawayVar;
		map = tdata( $map );
		reader = new ElevationReader( $smooth );
		reader.traceLevels( map, $channelRGBAV, $precisionX, $precisionY, $scaleX, $scaleY, $scaleZ );
		elevate = new Elevation;
		extrude = new SkinExtrude( elevate.generate( map, $channelRGBAV, $precisionX, $precisionY, $scaleX, $scaleY, $scaleZ ), {
			subdivision:1, recenter:true, coverall:true, closepath:false, bothsides:false, flip:false
		});
		if( param ){
			vars = param.vars;
			vars.materialCheck();
			if( vars._rotationX === 0 ){
				vars.rotationX = 90;
				vars._rotationX = -1;
			}
			param.apply( extrude );
		}
		addTree( $parent, $key, 'awayChild', extrude, param );
		addTree( '@DATA', $key + '@reader', 'data', reader, param );
	} );
}
final public function add3DS( $parent:String, $key:String, $3ds:String, ...$param ):void{
	var param:TAFparam;
	param = $paramGet( $param );
	orderPush( function():void{
		var call:Function;
		call = arguments.callee;
		max3ds( $parent, $key, tdata( $3ds ), param, call );
	} );
}
private function max3ds( $parent:String, $key:String, $3ds:ByteArray, $param:TAFparam, $callee:Function ):void{
	var parser:*, data:*, material:*, key:*, temp:*, end:*;
	parser = new Max3DS;
	parser.addEventListener( ParserEvent.PARSE_SUCCESS, function( $e:* ):void{
		var vars:TAFawayVar;
		$e.target.removeEventListener( $e.type, arguments.callee );
		if( $param ){
			vars = $param.vars;
			vars.materialCheck();
			if( vars._rotationX === 0 ){
				vars.rotationX = -90;
				vars._rotationX = -1;
			}
			$param.apply( $e.result );
		}
		addTree( $parent, $key, 'awayChild', $e.result, $param );
		orderCollect( $callee );
		poolCollectParam( $param );
	} );
	parser.parseGeometry( $3ds );
}
final public function addDae( $parent:String, $key:String, $dae:String, ...$param ):void{
	var param:TAFparam;
	param = $paramGet( $param );
	orderPush( function():void{
		var call:Function, temp:*;
		call = arguments.callee;
		temp = tdata( $dae ); 
		if( temp ){}else{
			temp = $dae; 
		}
		dae( $parent, $key, temp, param, call );
	} );
}
private function dae( $parent:String, $key:String, $dae:String, $param:TAFparam, $callee:Function ):void{
	var parser:*, container:*;
	parser = new Collada;
	parser.addEventListener( ParserEvent.PARSE_SUCCESS, function( $e:* ):void{
		var vars:TAFawayVar, key:*;
		$e.target.removeEventListener( $e.type, arguments.callee );
		if( $param ){
			vars = $param.vars;
			vars.materialCheck();
			if( vars._rotationX === 0 ){
				vars.rotationX = -90;
				vars._rotationX = -1;
			}
			$param.apply( $e.result );
		}
		addTree( $parent, $key, 'awayChild', $e.result, $param );
		for( key in $e.result.animationLibrary ){
			addTree( '@DATA', $key + '@' + key, 'daeAni', $e.result.animationLibrary.getAnimation( key ).animator, $param );
			addTree( '@DATA', $key + '@' + key + '.length', 'daeAniTime', $e.result.animationLibrary.getAnimation( key ).animator.length, $param );
		}
		orderCollect( $callee );
		poolCollectParam( $param );
	} );
	parser.parseGeometry( $dae );
}
final public function addContainer( $parent:String, $key:String, ...$param ):void{
	var param:TAFparam;
	param = $paramGet( $param );
	orderAddByKeyCheck( $key, param, function():void{
		addTree( $parent, $key, 'awayChild', poolPullObjectContainer3D( param ), param );
	} );
}
final public function addCube( $parent:String, $key:String, ...$param ):void{
	var param:TAFparam;
	param = $paramGet( $param );
	orderAddByKeyCheck( $key, param, function():void{
		addTree( $parent, $key, 'awayChild', poolPullCube( param ), param );
	} );
}
final public function addRect( $parent:String, $key:String, ...$param ):void{
	var param:TAFparam;
	param = $paramGet( $param );
	orderAddByKeyCheck( $key, param, function():void{
		addTree( $parent, $key, 'awayChild', poolPullPlane( param ), param );
	} );
}
final public function addBillboard( $parent:String, $key:String, ...$param ):void{
	var param:TAFparam;
	param = $paramGet( $param );
	orderAddByKeyCheck( $key, param, function():void{
		var plane:Plane, camera:Camera3D, listener:Function;
		plane = poolPullPlane( param );
		camera = tdata( $parent + '@camera' );
		listener = function ( $e:Object3DEvent ):void{ plane.rotationX = camera.rotationX+90; plane.rotationY = camera.rotationY; plane.rotationZ = camera.rotationZ; };
		camera.addOnPositionChange( listener );
		SELF._treeEvent[plane] = [camera.removeOnPositionChange, [listener]];
		addTree( $parent, $key, 'awayChild', plane, param );
	} );
}
final public function addSprite( $parent:String, $key:String, ...$param ):void{
	var param:TAFparam;
	param = $paramGet( $param );
	orderAddByKeyCheck( $key, param, function():void{
		addTree( $parent, $key, 'awaySprite', poolPullSprite3D( param ), param );
	} );
}
final public function addLightDirect( $parent:String, $key:String, ...$param ):void{
	var param:TAFparam;
	param = $paramGet( $param );
	orderAddByKeyCheck( $key, param, function():void{
		var data:Object;
		data = param.param;
		if( data.direction ){
			data.direction = new Vector3D( data.direction[0], data.direction[1], data.direction[2] );
		}else{
			error( 'direction이 [x,y,z] 형태로 지정되어야합니다.' );
		}
		addTree( $parent, $key, 'awayLight', new DirectionalLight3D( data ), param );
	} );
}
final public function addLightAmbient( $parent:String, $key:String, ...$param ):void{
	var param:TAFparam;
	param = $paramGet( $param );
	orderAddByKeyCheck( $key, param, function():void{
		var data:Object;
		data = param.param;
		addTree( $parent, $key, 'awayLight', new AmbientLight3D( data ), param );
	} );
}
final public function addLightPoint( $parent:String, $key:String, ...$param ):void{
	var param:TAFparam;
	param = $paramGet( $param );
	orderAddByKeyCheck( $key, param, function():void{
		var data:Object;
		data = param.param;
		addTree( $parent, $key, 'awayLight', new PointLight3D( data ), param );
	} );
}
//final public function addSphere( $parent:String, $key:String, ...$param ):void{
//	var param:TAFparam;
//	param = $paramGet( $param );
//	orderAddByKeyCheck( $key, function():void{
//		addTree( $parent, $key, 'awayChild', new Sphere( materialCheck( param[0] ) ), param ); 
//	} );
//}
//final public function addCylinder( $parent:String, $key:String, ...$param ):void{
//	var param:TAFparam;
//	param = $paramGet( $param );
//	orderAddByKeyCheck( $key, function():void{
//		addTree( $parent, $key, 'awayChild', new Cylinder( materialCheck( param[0] ) ), param ); 
//	} );
//}

//-----------------------------------------------------------------------------------------------------
//static public function addSwf( $key:String, $url:String, ...$param ):void{
//	
//}
//static public function addClass( $key:String, $url:String, ...$param ):void{
//	
//}

//public function addSky( $parent:String, $key:String, ...$param ):void{
//	orderAdd( function():void{
//		var sky:*, param:Object;
//		param = $paramMake( $param );
//		if( param.material is String ){
//			sky = new Skybox6( getMaterial( param.material ) );
//			sky.quarterFaces();
//		}else if( param.material ){
//			sky = new Skybox( 
//				getMaterial( $param.material.front ), 
//				getMaterial( $param.material.left ), 
//				getMaterial( $param.material.back ), 
//				getMaterial( $param.material.right ),
//				getMaterial( $param.material.up ),
//				getMaterial( $param.material.down )
//			);
//		}else{
//			error( 'material항목은 반드시 정의되어야합니다' );
//		}
//		setTree( 
//			$parent, $key, poolPullTree().init( 3, sky )
//		);
//	} );
//}
//------------------------------------------------------------------------------------------------------------


